home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_gene.lha / LEDA-3.1c-generic / incl / LEDA / impl / iv_tree.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-05  |  7.8 KB  |  303 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  iv_tree.h
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #ifndef LEDA_IV_TREE_H
  16. #define LEDA_IV_TREE_H
  17.  
  18. //--------------------------------------------------------------------
  19. //  
  20. //  Interval Trees
  21. //
  22. //  Michael Seel (1990/91)
  23. //
  24. // Implementation as described in
  25. // Kurt Mehlhorn: Data Structures and Algorithms 3, section VIII.5.1.1
  26. //
  27. //--------------------------------------------------------------------
  28.  
  29. // -----------------------------------------------------
  30. // includes
  31. // -----------------------------------------------------
  32.  
  33. #include <LEDA/basic.h>
  34. #include <LEDA/b_stack.h>
  35. #include <LEDA/list.h>
  36. #include <LEDA/dictionary.h>
  37.  
  38.  
  39.  
  40. // -------------------------------------------------------
  41. // declarations and definitions
  42. // -------------------------------------------------------
  43.  
  44. const BSTACKSIZE = 70 ; // according to tree.size and alpha
  45.                  // here: tree.size <= 10^9
  46.                  //       alpha = 0.25 ( worst case )
  47.  
  48. enum children { _left = 0 , _right = 1 };
  49. enum leaf_or_node { leaf = 0 , node = 1 } ;
  50.  
  51. class iv_node;
  52. class iv_tree;
  53.  
  54. typedef int       x_typ;
  55. typedef iv_node*  iv_item;
  56.  
  57.  
  58.  
  59.  
  60. // -----------------------------------------------------------
  61. // zur Unterscheidung bei Eingabe von Intervallen gleicher
  62. // x-Koordinate wird als Split-Value nicht nur die linke
  63. // Intervall-Grenze, sondern auch eine durchlaufende Nummer
  64. // als zweite Komponente abgespeichert, ueber der auch eine
  65. // compare Funktion deklariert wird.
  66. // -----------------------------------------------------------
  67.  
  68.  
  69. struct split_pair
  70.     {
  71.       x_typ key1;
  72.       int   key2;
  73.       split_pair(x_typ x=0,int n=0) { key1=x;key2=n; }
  74.       split_pair(split_pair& s) {key1=s.key1;key2=s.key2;}
  75.       int  cmp(x_typ x1,x_typ x2) {return int(x1)-int(x2);}
  76.       void print() {cout << "(" << key1 << "/" << key2 << ")"; }
  77.     };
  78.  
  79. typedef split_pair* split_item;
  80.  
  81. // -----------------------------------------------------------
  82. // zur Abspeicherung der x- und y-orientierten Knotenlisten !!
  83. // Die Dictionary-Deklaration wird nach erstellen der geeig-
  84. // neten bb_trees durch diese ersetzt. Bis dahin kostet bei
  85. // den rb_trees die Vereinigung zweier geordneter Listen 
  86. // (Laenge beider Listen insgesamt n) die Zeit O(n log n)
  87. // anstatt wie angestrebt O(n) !!!
  88. // -----------------------------------------------------------
  89.  
  90. // -------------------------------------------------------
  91. // interval, interval_item und query-Rueckgabetyp
  92. // -------------------------------------------------------
  93.  
  94. struct interval { x_typ koo1;
  95.           x_typ koo2;
  96.           interval(x_typ x,x_typ y) {koo1=x;koo2=y;}
  97.                   int cmp(x_typ x1,x_typ x2) {return int(x1)-int(x2);}
  98.                   void print() {cout << "[" << koo1 << "/" << koo2 << "]"; }
  99.                 };
  100.  
  101. typedef interval* interval_item;
  102.  
  103.  
  104. typedef list<interval_item> interval_list;
  105.  
  106. // -------------------------------------------------------------
  107. // compare-Funktion zu Dictionary
  108. // -------------------------------------------------------------
  109.  
  110. inline int compare (interval_item& p, interval_item& q)
  111. { int a = p->cmp(p->koo1,q->koo1);
  112.   return (a) ? a : p->cmp(p->koo2,q->koo2);
  113.  }
  114.  
  115.  
  116.  
  117. typedef dictionary<interval_item,int> nodelist;
  118. typedef nodelist* nodelist_p;
  119.  
  120. // -------------------------------------------------------
  121. // class iv_node     
  122. // -------------------------------------------------------
  123.  
  124. class iv_node {
  125.  
  126.   nodelist_p    x_nl;
  127.   nodelist_p    y_nl;
  128.   split_item    split_val;   // nach split_val (= Pointer auf das
  129.                  // Paar (linke Intervallgrenze;-lfnr)
  130.                  // wird geordnet
  131.   int gr;
  132.   iv_item son[2];
  133.  
  134.   friend class iv_tree;
  135.  
  136. public:
  137.  
  138.   nodelist_p    x_nodelist()           { return x_nl; }
  139.   nodelist_p    y_nodelist()           { return y_nl; }
  140.   split_item    split_value()          { return split_val; }
  141.  
  142.   int         blatt()                { return (gr==1); }
  143.   int         groesse()              { return gr; }
  144.  
  145.   float bal()
  146.     { if (blatt()) return 0.5;
  147.       else return float(float(son[_left]->groesse())/float(gr));
  148.         }
  149.  
  150.   iv_node(split_item s_i, leaf_or_node ln=leaf, iv_item ls=0, iv_item rs=0)
  151.   { 
  152.     x_nl = new nodelist;
  153.     y_nl = new nodelist;
  154.     split_val = new split_pair(*s_i);
  155.     son[_left] = ls;
  156.     son[_right] = rs;
  157.     if (ln==leaf)
  158.     gr=1;
  159.     else 
  160.     gr = ls->groesse()+rs->groesse();
  161.    }
  162.  
  163.  
  164.  ~iv_node()
  165.   { delete x_nl;
  166.     delete y_nl;
  167.     delete split_val;
  168.   }
  169.  
  170.   LEDA_MEMORY(iv_node)
  171.  
  172. }; 
  173.  
  174.  
  175. // -------------------------------------------------------
  176. // class iv_tree     
  177. // -------------------------------------------------------
  178.  
  179. class iv_tree {
  180.  
  181.   iv_item root;
  182.   int   anzahl; 
  183.   float alpha;
  184.   float d;
  185.   b_stack<iv_item> st;
  186.   int   interval_nb;         //  jedes Intervall, das eingefuegt wird,
  187.                  //  erhaelt eine laufende Nummer.
  188.                  //  in dieser Implementation wird diese
  189.                  //  mit dem Konstruktor auf 0 gesetzt
  190.                  //  und bei jedem Insert inkrementiert
  191.                  //  bei Dauerbenutzung einer Datenstruktur
  192.                  //  droht damit irgendwann ein Overflow.
  193.  
  194.   friend class iv_node;
  195.  
  196.   int cmp (const split_item& p, const split_item& q)
  197.     {
  198.        int a = p->cmp(p->key1,q->key1);
  199.        return (a) ? a : p->key2 -  q->key2;
  200.     }
  201.  
  202.   
  203.   void    lrot(iv_item , iv_item ); 
  204.   void    rrot(iv_item , iv_item ); 
  205.   void    ldrot(iv_item , iv_item ); 
  206.   void    rdrot(iv_item , iv_item ); 
  207.   void    reorganize_nodelist(iv_item , iv_item);
  208.   iv_item search(split_item);
  209.   iv_item ins(interval_item,interval_item,int);
  210.   iv_item sink(iv_item, interval_item, interval_item, int);
  211.   int     del(split_item);
  212.   void    deltree(iv_item);
  213.  
  214.   // split_in_interval ueberprueft ob die erste Komponente des split_value
  215.   // des Knotens v im Interval i liegt
  216.  
  217.   int   split_in_x_interval(iv_item v, interval_item i)
  218.     { if ((i->cmp(i->koo1 , split_value(v)->key1) <= 0)
  219.       && (i->cmp(split_value(v)->key1 , i->koo2) <= 0))
  220.         return 1;
  221.       else
  222.         return 0;
  223.         }
  224.  
  225.   int   split_in_y_interval(iv_item v, interval_item i)
  226.     { if ((i->cmp(i->koo2 , split_value(v)->key1) <= 0)
  227.       && (i->cmp(split_value(v)->key1 , i->koo1) <= 0))
  228.         return 1;
  229.       else
  230.         return 0;
  231.         }
  232.  
  233.   // nodelist_swap vertauscht die Knotenlisten zweier Knoten
  234.  
  235.   void    nodelist_swap(iv_item p, iv_item q)
  236.       { 
  237.         nodelist_p help = p->x_nl;
  238.         p->x_nl = q->x_nl;
  239.         q->x_nl = help;
  240.         help = p->y_nl;
  241.         p->y_nl = q->y_nl;
  242.         q->y_nl = help;
  243.           }
  244.  
  245.   void    y_search(interval_list& il, iv_item v, split_item ys, x_typ x, x_typ y);
  246.   void    check_nodelist(interval_list& il, iv_item v, x_typ x, x_typ y);
  247.   void    get_all_in_tree(interval_list& il, iv_item v);
  248.   void    take_all_iv(interval_list& il, iv_item v);
  249.   void    check_y_iv(interval_list& il, iv_item v, x_typ x);
  250.   void    check_x_iv(interval_list& il, iv_item v, x_typ y);
  251.  
  252.  
  253.   void pr_iv_tree(iv_item, int);
  254.   void pr_iv_list(iv_item);
  255.  
  256. public:
  257.  
  258.   nodelist_p    x_nodelist(iv_item it)   {return (it) ? it->x_nodelist() : 0;}
  259.   nodelist_p    y_nodelist(iv_item it)   {return (it) ? it->y_nodelist() : 0;}
  260.   split_item    split_value(iv_item it)  {return (it) ? it->split_value() : 0;}
  261.  
  262.  // Operationen auf Intervall-B"aumen:
  263.  
  264.   iv_item         iv_insert(x_typ, x_typ);
  265.   void            iv_delete(x_typ, x_typ);
  266.   interval_list   iv_query(x_typ, x_typ);
  267.  
  268.   // zur Datendarstellung folgende Ausgabe-Funktionen:
  269.  
  270.   void          print_split(iv_item);
  271.   void          text(string s) { cout << s; }
  272.   void          pr_list(interval_list& il);
  273.      
  274.   void pr_iv_tree() { pr_iv_tree(root,0); }
  275.  
  276.  
  277.   iv_tree()   :  st(BSTACKSIZE) 
  278.   { 
  279.     root = 0;
  280.     anzahl = 0;
  281.     alpha=0.28;
  282.     d=1/(2-alpha);
  283.     interval_nb = 0;
  284.   }
  285.  
  286.  
  287.   ~iv_tree()  
  288.   { 
  289.    if (root)
  290.      deltree(root);
  291.    root = 0;
  292.    anzahl = 0;
  293.    alpha = 0;
  294.    d = 0;
  295.    interval_nb = 0;
  296.   }
  297.  
  298. };
  299.  
  300.  
  301. #endif
  302.